local ffi = require("ffi")

ffi.cdef[[
	typedef struct {
		uint64_t id;
		uint32_t type;
		uint32_t idx;
	} chkid_t;

	typedef chkid_t fileid_t;
	typedef unsigned long int uint64_t;

	typedef struct {
		int16_t id;
	} nid_t;

	typedef struct {
		nid_t id;
		uint16_t status;
	} reploc_t;

	typedef struct {
		chkid_t  id;
		uint16_t magic;
		uint16_t repnum;
		uint32_t mtime;
		uint64_t info_version;
		uint64_t snap_version;
		reploc_t diskid[0];
	} chkinfo_t;

	typedef struct {
		nid_t nid;
		uint32_t type;
		uint32_t status;
		uint64_t used;
		uint64_t total;
		uint64_t load;
	} nodestat_t;

	typedef struct {
		nodestat_t *stat;
		char *clustername;
		char *nodename;
		char *status;
		char *admin;
		char *quorum;
		char *home;
		uint32_t *uptime;
	} nodeinfo_t;

	typedef enum {
		__DONT_CHANGE = 0,
		__SET_TO_SERVER_TIME,
		__SET_TO_CLIENT_TIME,
	} __time_how;

	typedef struct {
		int set_it;
		uint32_t mode;
	} __set_mode;

	typedef struct {
		int set_it;
		uint32_t uid;
	} __set_uid;

	typedef struct {
		int set_it;
		uint32_t gid;
	} __set_gid;

	typedef struct {
		int set_it;
		uint64_t size;
	} __set_size;

	typedef struct {
		uint32_t seconds;
		uint32_t nseconds;
	} __time;

	typedef struct {
		__time_how set_it;
		__time time;
	} __set_time;

	typedef struct {
		int set_it;
		uint32_t replica;
	} __set_replica;

	typedef struct {
		int set_it;
		uint32_t clone;
	} __set_clone;

	typedef struct {
		int set_it;
		uint32_t protect;
	} __set_protect;

	typedef struct {
		int set_it;
		uint32_t priority;
	} __set_priority;

	typedef struct {
		int set_it;
		uint32_t localize;
	} __set_localize;

	typedef struct {
		int set_it;
		uint32_t multpath;
	} __set_multpath;

	typedef struct {
		int set_it;
		uint32_t writeback;
	} __set_writeback;

	typedef struct {
		__set_mode mode;
		__set_uid uid;
		__set_gid gid;
		__set_size size;
		__set_time atime;
		__set_time btime;
		__set_time ctime;
		__set_time mtime;
		__set_replica replica;
		__set_clone clone;
		__set_protect protect;
		__set_priority priority;
		__set_localize localize;
		__set_multpath multpath;
		__set_writeback writeback;
	} setattr_t;

	typedef struct {
		fileid_t id;
		uint16_t magic;
		uint16_t repnum;
		uint64_t snap_rollback;
		uint64_t snap_version;
		uint64_t reference;
		uint32_t attr;
		int32_t  priority;
		uint32_t __pad__[4];
		uint64_t size;
		uint32_t mode;
		uint32_t uid;
		uint32_t gid;
		uint32_t ctime;
		uint32_t mtime;
		uint32_t btime;
		uint32_t atime;
	} fileinfo_t;

	typedef struct {
		nid_t nid;
		uint32_t type;
		uint32_t status;
		uint64_t used;
		uint64_t total;
		float percent;
		char site[64];
		char rack[64];
		char node[64];
	} b_node_info_t;

    typedef struct {
        int node_count;
        b_node_info_t nodes[200];

        int writeable_count;
        b_node_info_t *writeable_nodes[200];

        b_node_info_t *nid_map[200];

        float average;
    } b_node_list_t;

	typedef unsigned char uuid_t[16];

	int env_init_simple(const char *name);
	int network_connect_master(void);
	int stor_init(const char *home, uint64_t  max_object);

	int stor_splitpath(const char *_path, fileid_t *parent, char *name);
	int stor_mkpool_with_area(const fileid_t *parent, const char *name, const char *site_name, const setattr_t *_setattr, fileid_t *_fileid);
	int stor_mkvol_with_area(fileid_t *_fileid, const fileid_t *parent, const char *name, int priority, const char *site_name, const setattr_t *_setattr, uint32_t repnum);
	int stor_rmpool(const fileid_t *parent, const char *name);
	int stor_lookup(const fileid_t *parent, const char *name, fileid_t *id);
	int stor_lookup1(const char *path, fileid_t *id);
	int stor_rmvol(const fileid_t *parent, const char *name);
	int stor_rename(const fileid_t *fromdir, const char *fromname, const fileid_t *todir, const char *toname);
	int stor_truncate(const fileid_t *id, uint64_t length);

	extern void get_uuid(char *uuid);
	extern void uuid_generate(uuid_t out);
	extern void uuid_unparse(const uuid_t uu, char *out);

	int stor_listpool_open(const fileid_t *id, const char *uuid);
	int stor_listpool(const fileid_t *fileid, const char *uuid, uint64_t offset, void **_de, int *_delen);
	int stor_listpool_close(const fileid_t *id, const char *uuid);

	int node_getinfo(nodeinfo_t *info, const char *name);

	int dispatch_list_storage_area(char *buf, int *count);

	int cluster_listnode_open(const char *uuid);
	int cluster_listnode(char *buf, int *buflen, const char *uuid, uint64_t offset);
	int cluster_listnode_close(const char *uuid);

	const void *_opaque_decode(const void *buf, uint32_t len, ...);

	int printf(const char *fmt, ...);
]]
